package org.aristotle.auth.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.util.Strings;
import org.aristotle.auth.constant.SysAuthConstant;
import org.aristotle.auth.dto.Oauth2TokenDTO;
import org.aristotle.auth.service.UserService;
import org.aristotle.common.response.ResponseEntity;
import org.aristotle.common.response.result.Result;
import org.aristotle.common.response.result.ResultCode;
import org.aristotle.user.model.dto.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.KeyPair;
import java.security.Principal;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.util.Map;

@RestController
@RequestMapping("/oauth")
public class AuthController {

    @Autowired
    private KeyPair keyPair;

    @Autowired
    private UserService userService;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @RequestMapping(value = "/token", method = RequestMethod.POST)
    public Result<Oauth2TokenDTO> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        Oauth2TokenDTO oauth2TokenDTO = Oauth2TokenDTO.builder()
                .accessToken(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn())
                .tokenType("Bearer")
                .scope(oAuth2AccessToken.getScope().toString())
                .userId(oAuth2AccessToken.getAdditionalInformation().get("userId").toString())
                .jti(oAuth2AccessToken.getAdditionalInformation().get("jti").toString())
                .build();
        return new Result<>(ResultCode.AUTH_SUCCESS.getCode(),ResultCode.AUTH_SUCCESS.getMsg(),oauth2TokenDTO);
    }

    @ApiOperation(value = "获取公钥")
    @GetMapping("/publicKey")
    public Map<String,Object> getPublicKey() {
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAKey key = new RSAKey.Builder(publicKey).build();
        return new JWKSet(key).toJSONObject();
    }

    @GetMapping("getUser")
    public Result<?> getUser(@RequestHeader("Authorization")String accessToken) throws ParseException {
        System.out.println(accessToken);

        accessToken = StrUtil.replaceIgnoreCase(accessToken, SysAuthConstant.JWT_PREFIX, Strings.EMPTY);

        String payload = StrUtil.toString(JWSObject.parse(accessToken).getPayload());
        JSONObject jsonObject = JSONUtil.parseObj(payload);
        String username = jsonObject.getStr("user_name");
        UserDTO userDTO = userService.getByUsername(username);
        return ResponseEntity.ok(userDTO);
    }

}
